package me.zhengjie.modules.system.service.impl;

import com.ecc.shuffle.upgrade.RuleFirer;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import me.zhengjie.config.MappingProperties;
import me.zhengjie.config.ShuffleProperties;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.SafeRiskItem;
import me.zhengjie.modules.system.domain.SafeRiskType;
import me.zhengjie.modules.system.repository.SafeRiskItemRepository;
import me.zhengjie.modules.system.repository.SafeRiskTypeRepository;
import me.zhengjie.modules.system.service.SafeTestItemService;
import me.zhengjie.modules.system.service.SafeTestTypeService;
import me.zhengjie.modules.system.vo.SafeRiskItemVo;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.*;

/**
 * SafeRiskTypeServiceImpl
 *
 * @author guoyuan
 * @version 1.0.0
 * @since 1.0.0
 */
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "safeTestItem")
public class SafeTestItemServiceImpl implements SafeTestItemService {
    private final SafeRiskItemRepository safeRiskItemRepository;
    private final SafeRiskTypeRepository safeRiskTypeRepository;
    private final MappingProperties mappingProperties;
    private final ShuffleProperties shuffleProperties;

    @Autowired
    SafeTestTypeService safeTestTypeService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(SafeRiskItem entity) {
        safeRiskItemRepository.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        safeRiskItemRepository.deleteById(id);
    }

    @Override
    public List<SafeRiskItem> queryAll(SafeRiskItemVo vo) throws Exception {
        return safeRiskItemRepository.findAll();
    }

    @Override
    public List<SafeRiskItem> queryByTypeId(String typeId) throws Exception {
        List<SafeRiskItem> result = new ArrayList<>();
        String level = "LEVEL";
        String[] split = typeId.split(",");
        for (int i = 0; i < split.length; i++) {
            if("".equals(split[i]))continue;
            List<SafeRiskType> pramList = Lists.newArrayList();
            final Optional<SafeRiskType> byId = safeRiskTypeRepository.findById(split[i]);
            if (!byId.isPresent()) {
                throw new BadRequestException("场景风险类别[" + split[i] + "]不存在");
            }
            queryParent(pramList, byId.get());
            // 第一个是叶子节点，最后一个是根节点，反转list
            Collections.reverse(pramList);
            Map<String, Object> param = Maps.newHashMap();
            for (int j = 0; j < pramList.size(); j++) {
                param.put(level + (j + 1), pramList.get(j).getLevel());
            }
            Map<String, Object> fire = RuleFirer.fire(shuffleProperties.getRuleSetId(), shuffleProperties.getRuleId(), param);
            if(fire.get("SAFE_RULES") instanceof  ArrayList){
                List<Map<String,Object>> safeRules = (ArrayList) fire.get("SAFE_RULES");
                safeRules.forEach(rule ->{
                    result.add(mapToBeanList(rule));
                });
            }
        }
        return result;

    }

    public static SafeRiskItem mapToBeanList(Map<String,Object> map){
        SafeRiskItem riskItem = new SafeRiskItem();
        try {
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
//        "create_time" -> {Timestamp@17086} "2021-11-25 15:33:02.0"
            riskItem.setCreateTime(timestamp.valueOf(map.get("create_time").toString()));
//        "type_id" -> "4028a35a7d56001e017d560313840032"
//        "correspondence" -> "安全开发测试规范_注销_1"
            riskItem.setCorrespondence(map.get("correspondence") == null ? "" : map.get("correspondence").toString());
//        "case_name" -> "个人用户注销"
            riskItem.setCaseName(map.get("case_name") == null ? "" : map.get("case_name").toString());
//        "scene_type" -> "0"
            riskItem.setSceneType(map.get("scene_type") == null ? "" : map.get("scene_type").toString());
//        "point" -> "(1)个人用户注销"
            riskItem.setPoint(map.get("point") == null ? "" : map.get("point").toString());
//        "create_by" -> "admin"
            riskItem.setCreateBy(map.get("create_by") == null ? "" : map.get("create_by").toString());
//        "risk_level" -> "一般"
            riskItem.setRiskLevel(map.get("risk_level") == null ? "" : map.get("risk_level").toString());
//        "update_time" -> {Timestamp@17102} "2021-11-25 15:33:02.0"
            riskItem.setUpdateTime(timestamp.valueOf(map.get("update_time").toString()));
//        "business_type" -> "业务功能\n(FNC)"
            riskItem.setBusinessType(map.get("business_type") == null ? "" : map.get("business_type").toString());
//        "scope" -> "客户服务类"
            riskItem.setScope(map.get("scope") == null ? "" : map.get("scope").toString());
//        "case_id" -> "SEC_BUS_FNC_ID_004"
            riskItem.setCaseId(map.get("case_id") == null ? "" : map.get("case_id").toString());
//        "test_method" -> "系统测试"
            riskItem.setTestMethod(map.get("test_method") == null ? "" : map.get("test_method").toString());
//        "risk" -> "用户注销"
            riskItem.setRisk(map.get("risk") == null ? "" : map.get("risk").toString());
//        "id" -> "4028a35a7d56001e017d560313850033"
            riskItem.setId(map.get("id") == null ? "" : map.get("id").toString());
//        "update_by" -> "admin"
            riskItem.setUpdateBy(map.get("update_by") == null ? "" : map.get("update_by").toString());
//        "env_type" -> "用户标识与鉴别\n(注册/登录)\n(ID)"
            riskItem.setEnvType(map.get("env_type") == null ? "" : map.get("env_type").toString());
//        "app_env" -> "用户注册/开户/注销"
            riskItem.setAppEnv(map.get("app_env") == null ? "" : map.get("app_env").toString());
//        "apply_type" -> "web/app/公众号"
            riskItem.setApplyType(map.get("apply_type") == null ? "" : map.get("apply_type").toString());
        }catch (Exception e){
            e.printStackTrace();
        }
        return riskItem;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SafeRiskItem entity) throws Exception {
        safeRiskItemRepository.save(entity);
    }

    private void queryParent(List<SafeRiskType> pramList, SafeRiskType safeRiskType) {
        pramList.add(safeRiskType);
        final String parentId = safeRiskType.getParentId();
        if (StringUtils.isBlank(parentId)) {
            return;
        }
        final Optional<SafeRiskType> byId = safeRiskTypeRepository.findById(parentId);
        if (!byId.isPresent()) {
            return;
        }
        queryParent(pramList, byId.get());
    }

}
